package com.zwcl.glass.tools.controller;


import com.zwcl.common.core.domain.entity.ApiResult;
import com.zwcl.common.core.enums.ExceptionCode;
import com.zwcl.common.core.exception.BusinessException;
import com.zwcl.common.core.redis.RedisLock;
import com.zwcl.common.core.utils.JsonUtils;
import com.zwcl.glass.tools.dto.HasTestDto;
import com.zwcl.glass.tools.dto.TestRecordDto;
import com.zwcl.glass.tools.entity.AnswerResult;
import com.zwcl.glass.tools.entity.TestRecord;
import com.zwcl.glass.tools.service.PaperService;
import com.zwcl.glass.tools.service.TestRecordService;
import com.zwcl.glass.tools.vo.TestRecordVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author xieyongping
 * @since 2021-01-07
 */
@RestController
@RequestMapping("/testRecord")
@Slf4j
public class TestRecordController {
    @Autowired
    private TestRecordService testRecordService;

    @Autowired
    private PaperService paperService;

    @Autowired
    private RedisLock redisLock;

    private final String saveRecordRedisLockKey="RedisLock:Paper:SaveRecord:";

    /**
     * 用户测试次数
     */
    @PostMapping("/hasTest")
    public Boolean userHasTest(@RequestBody HasTestDto dto){
        Integer count = testRecordService.getUserTestTimes(dto);
        return count>0? true:false;
    }

    /**
     * 查询测试记录
     */
    @PostMapping("/getRecord")
    //@OperationLog(name = "查询测试记录", type = OperationLogType.OTHER)
    //@ApiOperation(value = "查询测试记录-有用", response = TestRecord.class)
    public ApiResult<List<TestRecordVO>> getTestRecords(@RequestBody HasTestDto dto) throws Exception {
        if(dto.getUserId()==null && dto.getPaperId()==null && dto.getPhone()==null){
            throw new BusinessException(ExceptionCode.PARAMETER_EXCEPTION);
        }
        List<TestRecord> testRecords = testRecordService.getUserTestRecords(dto);
        List<TestRecordVO> voList=new ArrayList<>();
        testRecords.forEach(item->{
            TestRecordVO vo=new TestRecordVO();
            BeanUtils.copyProperties(item,vo);
            //TODO:根据类型转换为具体的题型
            List<AnswerResult> answerResults= JsonUtils.jsonToList(item.getTestResult(), AnswerResult.class);
            vo.setTestResultList(answerResults);
            voList.add(vo);
        });
        return ApiResult.ok(voList);
    }

    /**
     * 保存测试记录
     */
    @PostMapping("/saveRecord")
    //@OperationLog(name = "保存测试记录", type = OperationLogType.OTHER)
    //@ApiOperation(value = "保存测试记录-有用", response = TestRecord.class)
    public ApiResult<TestRecordVO> saveTestRecords(@RequestBody TestRecordDto dto) throws Exception {
        if(dto.getUserId()==null || dto.getPaperId()==null){
            throw new BusinessException(ExceptionCode.PARAMETER_EXCEPTION);
        }
        //TODO:先去掉锁
//        if(!redisLock.tryLock(saveRecordRedisLockKey+dto.getPaperId()+"#"+dto.getUserId(),1 * 30 * 1000L)){
//            throw new BusinessException("正在保存中，请勿重复提交！");
//        }
        //TODO:用来测试，获取用户测试记录，后面要删除
//        TestRecord testRecordTmp = testRecordService.getUserTestRecord(dto);
//        List<AnswerResult> answerResults= JsonUtils.jsonToList(testRecordTmp.getTestResult(), AnswerResult.class);
//        dto.setResultList(answerResults);
        try {
            //计算测试结论
            //List<String> conclusionList = testRecordService.generateTestConclusion(dto);
            Map<String,List<String>> conclusionAndTagMap = testRecordService.generateTestConclusionEx(dto);
            List<String> conclusionList=conclusionAndTagMap.get("conclusion");
            List<String> tagList = conclusionAndTagMap.get("tags");
            String conclusion= (null!=conclusionList&&conclusionList.size()>0) ? StringUtils.join(conclusionList, " ; ") : null;
            String tags = (null!=tagList&&tagList.size()>0) ? StringUtils.join(tagList, " ; ") : null;
            //获取用户测试记录，测试多次覆盖的代码
//            TestRecord testRecord = testRecordService.getUserTestRecord(dto);
//            //更新测试记录
//            if (testRecord == null) {
//                //新增测试记录
//                testRecord = new TestRecord();
//                testRecord.setPaperId(dto.getPaperId());
//                testRecord.setUserId(dto.getUserId());
//                testRecord.setPhone(dto.getPhone());
//            }
//            testRecord.setTestTime(new Date());
//            testRecord.setTestResult(JsonUtils.objectToJson(dto.getResultList()));
//            testRecord.setAutoConclusion(conclusion);

            // 测试多次记录多次
            TestRecord testRecord = new TestRecord();
            testRecord.setPaperId(dto.getPaperId());
            testRecord.setPaperCode(dto.getPaperCode());
            testRecord.setUserId(dto.getUserId());
            testRecord.setPhone(dto.getPhone());
            testRecord.setTestTime(new Date());
            testRecord.setTestResult(JsonUtils.objectToJson(dto.getResultList()));
            testRecord.setAutoConclusion(conclusion);
            testRecord.setAutoTags(tags);

            Boolean succFlag=true;
            if(testRecord.getId()==null){
                succFlag=testRecordService.saveTestRecord(testRecord);
            }else {
                succFlag=testRecordService.updateTestRecord(testRecord);
            }
            //更新测试的人次
            paperService.updateTestNum(dto.getPaperId());
            TestRecordVO vo=new TestRecordVO();
            vo.setUserId(testRecord.getUserId());
            vo.setPaperId(testRecord.getPaperId());
            vo.setTestTime(testRecord.getTestTime());
            vo.setAutoConclusion(conclusion);
            vo.setAutoTags(tags);

            return ApiResult.ok(vo);
        }catch (Exception ex){
            log.error(ex.getMessage());
            throw new BusinessException("保存用户结果失败，"+ex.getMessage());
        }finally {
            redisLock.unlock(saveRecordRedisLockKey+dto.getPaperId()+"#"+dto.getUserId());
        }
    }


}

